/**
 * @Author: chancoki chhj727@163.com
 * @Date: 2025-03-04 17:22:27
 * @LastEditors: chancoki chhj727@163.com
 * @LastEditTime: 2025-03-05 14:56:44
 * @Copyright (c) 2025 by chancoki, All Rights Reserved.
 **/
const XLSX = require("xlsx");
const { exec } = require("child_process");
const { promisify } = require("util");
const execAsync = promisify(exec);
const path = require("path");
const fs = require("fs");

// 确保logs目录存在
const getLogsDir = () => {
  const baseDir = process.pkg ? process.cwd() : __dirname;
  return path.join(baseDir, "logs");
};

const logsDir = getLogsDir();
if (!fs.existsSync(logsDir)) {
  try {
    fs.mkdirSync(logsDir, { recursive: true });
  } catch (error) {
    console.error("创建logs目录失败:", error);
  }
}

// 读取Excel文件中的IP列表
function readIPList(filePath) {
  try {
    const workbook = XLSX.readFile(filePath);
    const sheetName = workbook.SheetNames[0];
    const worksheet = workbook.Sheets[sheetName];
    const data = XLSX.utils.sheet_to_json(worksheet);
    return data.map((row) => Object.values(row)[0]);
  } catch (error) {
    console.error("读取Excel文件失败:", error);
    return [];
  }
}

// 连接设备
async function connectDevice(ip) {
  try {
    const { stdout } = await execAsync(`adb connect ${ip}`);

    if (!stdout.includes("connected to")) {
      console.log(`连接设备失败 [${ip}]: ${stdout}`);
      return false;
    }
    console.log(`成功连接到设备: [${ip}]`);
    return true;
  } catch (error) {
    console.error(`连接设备失败 [${ip}]:`, error);
    return false;
  }
}

// 安装APK
async function installAPK(ip, apkPath, packageName, activity) {
  try {
    await execAsync(`adb -s ${ip} install -r -d ${apkPath}`);
    console.log(`成功在设备 [${ip}] 上安装APK`);

    // 启动应用
    try {
      const { stderr } = await execAsync(`adb -s ${ip} shell am start -n ${packageName}/${activity}`);

      if (stderr !== "") {
        console.log(`在设备 [${ip}] 上启动应用失败:`, stderr);
        return false;
      }
      console.log(`成功在设备 [${ip}] 上启动应用`);
    } catch (error) {
      console.error(`在设备 [${ip}] 上启动应用失败:`, error);
      return false;
    }

    return true;
  } catch (error) {
    console.error(`在设备 [${ip}] 上安装APK失败:`, error);
    return false;
  }
}

// 断开设备连接
async function disconnectDevice(ip) {
  try {
    await execAsync(`adb disconnect ${ip}`);
    console.log(`成功断开设备连接: [${ip}]`);
  } catch (error) {
    console.error(`断开设备连接失败 [${ip}]:`, error);
  }
}

// 主函数
async function main() {
  const packageJson = require("./package.json");

  console.log(`
....###....########..########..........########.....###....########..######..##.....##.
...##.##...##.....##.##.....##.........##.....##...##.##......##....##....##.##.....##.
..##...##..##.....##.##.....##.........##.....##..##...##.....##....##.......##.....##.
.##.....##.##.....##.########..#######.########..##.....##....##....##.......#########.
.#########.##.....##.##.....##.........##.....##.#########....##....##.......##.....##.
.##.....##.##.....##.##.....##.........##.....##.##.....##....##....##....##.##.....##.
.##.....##.########..########..........########..##.....##....##.....######..##.....##.

version ${packageJson.version} by ${packageJson.author.name}

`);

  if (process.argv.length < 6) {
    console.log(
      "使用方法: ./adb-batch.exe <Excel文件路径> <APK文件路径> <包名> <Activity>\n例如: ./adb-batch.exe list.xls app.apk uni.UNI3862FA9 io.dcloud.PandoraEntry",
    );
    return;
  }
  const excelPath = path.resolve(process.argv[2]);
  const apkPath = path.resolve(process.argv[3]);
  const packageName = process.argv[4];
  const activity = process.argv[5];

  // 读取IP列表
  const ipList = readIPList(excelPath);
  if (ipList.length === 0) {
    console.log("没有找到IP地址");
    return;
  }

  console.log("开始批量安装APK...");

  // 记录失败的设备
  const failedDevices = [];

  // 批量处理设备
  for (const ip of ipList) {
    console.log(`\n处理设备: [${ip}]`);

    // 连接设备
    const connected = await connectDevice(ip);
    if (!connected) {
      failedDevices.push({ ip, reason: "连接失败" });
      continue;
    }

    // 安装APK
    const installed = await installAPK(ip, apkPath, packageName, activity);
    if (!installed) {
      failedDevices.push({ ip, reason: "安装或启动失败" });
    }

    // 断开连接
    await disconnectDevice(ip);
  }

  console.log("\n批量安装完成!");

  // 打印失败设备列表
  if (failedDevices.length > 0) {
    console.log("\n安装失败的设备列表:");
    failedDevices.forEach(({ ip, reason }) => {
      console.log(`- [${ip}]: ${reason}`);
    });
    // 导出失败设备列表
    exportFailedDevices(failedDevices);
  } else {
    console.log("\n所有设备安装成功!");
  }
}

// 导出失败设备列表到文件
function exportFailedDevices(failedDevices) {
  if (failedDevices.length === 0) return;

  const now = new Date();
  const timestamp = now.toISOString().replace(/[:.]/g, "-").slice(0, 19);
  const fileName = path.join(getLogsDir(), `failed_devices_${timestamp}.txt`);
  const content = failedDevices.map(({ ip, reason }) => `[${ip}]: ${reason}`).join("\n");

  try {
    fs.writeFileSync(fileName, content);
    console.log(`\n失败设备列表已导出到文件: ${fileName}`);
  } catch (error) {
    console.error("导出失败设备列表失败:", error);
  }
}

// 运行主函数
main().catch((error) => {
  console.error("程序执行出错:", error);
});
